home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / configDialog.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  45KB  |  1,088 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''IDLE Configuration Dialog: support user customization of IDLE by GUI
  5.  
  6. Customize font faces, sizes, and colorization attributes.  Set indentation
  7. defaults.  Customize keybindings.  Colorization and keybindings can be
  8. saved as user defined sets.  Select startup options including shell/editor
  9. and default window size.  Define additional help sources.
  10.  
  11. Note that tab width in IDLE is currently fixed at eight due to Tk issues.
  12. Refer to comments in EditorWindow autoindent code for details.
  13.  
  14. '''
  15. from Tkinter import *
  16. import tkMessageBox
  17. import tkColorChooser
  18. import tkFont
  19. import string
  20. import copy
  21. from configHandler import idleConf
  22. from dynOptionMenuWidget import DynOptionMenu
  23. from tabpage import TabPageSet
  24. from keybindingDialog import GetKeysDialog
  25. from configSectionNameDialog import GetCfgSectionNameDialog
  26. from configHelpSourceEdit import GetHelpSourceDialog
  27.  
  28. class ConfigDialog(Toplevel):
  29.     
  30.     def __init__(self, parent, title):
  31.         Toplevel.__init__(self, parent)
  32.         self.configure(borderwidth = 5)
  33.         self.geometry('+%d+%d' % (parent.winfo_rootx() + 20, parent.winfo_rooty() + 30))
  34.         self.themeElements = {
  35.             'Normal Text': ('normal', '00'),
  36.             'Python Keywords': ('keyword', '01'),
  37.             'Python Definitions': ('definition', '02'),
  38.             'Python Builtins': ('builtin', '03'),
  39.             'Python Comments': ('comment', '04'),
  40.             'Python Strings': ('string', '05'),
  41.             'Selected Text': ('hilite', '06'),
  42.             'Found Text': ('hit', '07'),
  43.             'Cursor': ('cursor', '08'),
  44.             'Error Text': ('error', '09'),
  45.             'Shell Normal Text': ('console', '10'),
  46.             'Shell Stdout Text': ('stdout', '11'),
  47.             'Shell Stderr Text': ('stderr', '12') }
  48.         self.ResetChangedItems()
  49.         self.CreateWidgets()
  50.         self.resizable(height = FALSE, width = FALSE)
  51.         self.transient(parent)
  52.         self.grab_set()
  53.         self.protocol('WM_DELETE_WINDOW', self.Cancel)
  54.         self.parent = parent
  55.         self.tabPages.focus_set()
  56.         self.LoadConfigs()
  57.         self.AttachVarCallbacks()
  58.         self.wait_window()
  59.  
  60.     
  61.     def CreateWidgets(self):
  62.         self.tabPages = TabPageSet(self, pageNames = [
  63.             'Fonts/Tabs',
  64.             'Highlighting',
  65.             'Keys',
  66.             'General'])
  67.         self.tabPages.ChangePage()
  68.         frameActionButtons = Frame(self)
  69.         self.buttonHelp = Button(frameActionButtons, text = 'Help', command = self.Help, takefocus = FALSE)
  70.         self.buttonOk = Button(frameActionButtons, text = 'Ok', command = self.Ok, takefocus = FALSE)
  71.         self.buttonApply = Button(frameActionButtons, text = 'Apply', command = self.Apply, takefocus = FALSE)
  72.         self.buttonCancel = Button(frameActionButtons, text = 'Cancel', command = self.Cancel, takefocus = FALSE)
  73.         self.CreatePageFontTab()
  74.         self.CreatePageHighlight()
  75.         self.CreatePageKeys()
  76.         self.CreatePageGeneral()
  77.         self.buttonHelp.pack(side = RIGHT, padx = 5, pady = 5)
  78.         self.buttonOk.pack(side = LEFT, padx = 5, pady = 5)
  79.         self.buttonApply.pack(side = LEFT, padx = 5, pady = 5)
  80.         self.buttonCancel.pack(side = LEFT, padx = 5, pady = 5)
  81.         frameActionButtons.pack(side = BOTTOM)
  82.         self.tabPages.pack(side = TOP, expand = TRUE, fill = BOTH)
  83.  
  84.     
  85.     def CreatePageFontTab(self):
  86.         self.fontSize = StringVar(self)
  87.         self.fontBold = BooleanVar(self)
  88.         self.fontName = StringVar(self)
  89.         self.spaceNum = IntVar(self)
  90.         self.editFont = tkFont.Font(self, ('courier', 10, 'normal'))
  91.         frame = self.tabPages.pages['Fonts/Tabs']['page']
  92.         frameFont = Frame(frame, borderwidth = 2, relief = GROOVE)
  93.         frameIndent = Frame(frame, borderwidth = 2, relief = GROOVE)
  94.         labelFontTitle = Label(frameFont, text = 'Set Base Editor Font')
  95.         frameFontName = Frame(frameFont)
  96.         frameFontParam = Frame(frameFont)
  97.         labelFontNameTitle = Label(frameFontName, justify = LEFT, text = 'Font :')
  98.         self.listFontName = Listbox(frameFontName, height = 5, takefocus = FALSE, exportselection = FALSE)
  99.         self.listFontName.bind('<ButtonRelease-1>', self.OnListFontButtonRelease)
  100.         scrollFont = Scrollbar(frameFontName)
  101.         scrollFont.config(command = self.listFontName.yview)
  102.         self.listFontName.config(yscrollcommand = scrollFont.set)
  103.         labelFontSizeTitle = Label(frameFontParam, text = 'Size :')
  104.         self.optMenuFontSize = DynOptionMenu(frameFontParam, self.fontSize, None, command = self.SetFontSample)
  105.         checkFontBold = Checkbutton(frameFontParam, variable = self.fontBold, onvalue = 1, offvalue = 0, text = 'Bold', command = self.SetFontSample)
  106.         frameFontSample = Frame(frameFont, relief = SOLID, borderwidth = 1)
  107.         self.labelFontSample = Label(frameFontSample, text = 'AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', justify = LEFT, font = self.editFont)
  108.         frameIndentSize = Frame(frameIndent)
  109.         labelSpaceNumTitle = Label(frameIndentSize, justify = LEFT, text = 'Python Standard: 4 Spaces!')
  110.         self.scaleSpaceNum = Scale(frameIndentSize, variable = self.spaceNum, label = 'Indentation Width', orient = 'horizontal', tickinterval = 2, from_ = 2, to = 16)
  111.         frameFont.pack(side = LEFT, padx = 5, pady = 10, expand = TRUE, fill = BOTH)
  112.         frameIndent.pack(side = LEFT, padx = 5, pady = 10, fill = Y)
  113.         labelFontTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  114.         frameFontName.pack(side = TOP, padx = 5, pady = 5, fill = X)
  115.         frameFontParam.pack(side = TOP, padx = 5, pady = 5, fill = X)
  116.         labelFontNameTitle.pack(side = TOP, anchor = W)
  117.         self.listFontName.pack(side = LEFT, expand = TRUE, fill = X)
  118.         scrollFont.pack(side = LEFT, fill = Y)
  119.         labelFontSizeTitle.pack(side = LEFT, anchor = W)
  120.         self.optMenuFontSize.pack(side = LEFT, anchor = W)
  121.         checkFontBold.pack(side = LEFT, anchor = W, padx = 20)
  122.         frameFontSample.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  123.         self.labelFontSample.pack(expand = TRUE, fill = BOTH)
  124.         frameIndentSize.pack(side = TOP, padx = 5, pady = 5, fill = BOTH)
  125.         labelSpaceNumTitle.pack(side = TOP, anchor = W, padx = 5)
  126.         self.scaleSpaceNum.pack(side = TOP, padx = 5, fill = X)
  127.         return frame
  128.  
  129.     
  130.     def CreatePageHighlight(self):
  131.         self.builtinTheme = StringVar(self)
  132.         self.customTheme = StringVar(self)
  133.         self.fgHilite = BooleanVar(self)
  134.         self.colour = StringVar(self)
  135.         self.fontName = StringVar(self)
  136.         self.themeIsBuiltin = BooleanVar(self)
  137.         self.highlightTarget = StringVar(self)
  138.         frame = self.tabPages.pages['Highlighting']['page']
  139.         frameCustom = Frame(frame, borderwidth = 2, relief = GROOVE)
  140.         frameTheme = Frame(frame, borderwidth = 2, relief = GROOVE)
  141.         self.textHighlightSample = Text(frameCustom, relief = SOLID, borderwidth = 1, font = ('courier', 12, ''), cursor = 'hand2', width = 21, height = 10, takefocus = FALSE, highlightthickness = 0, wrap = NONE)
  142.         text = self.textHighlightSample
  143.         text.bind('<Double-Button-1>', (lambda e: 'break'))
  144.         text.bind('<B1-Motion>', (lambda e: 'break'))
  145.         textAndTags = (('#you can click here', 'comment'), ('\n', 'normal'), ('#to choose items', 'comment'), ('\n', 'normal'), ('def', 'keyword'), (' ', 'normal'), ('func', 'definition'), ('(param):', 'normal'), ('\n  ', 'normal'), ('"""string"""', 'string'), ('\n  var0 = ', 'normal'), ("'string'", 'string'), ('\n  var1 = ', 'normal'), ("'selected'", 'hilite'), ('\n  var2 = ', 'normal'), ("'found'", 'hit'), ('\n  var3 = ', 'normal'), ('list', 'builtin'), ('(', 'normal'), ('None', 'builtin'), (')\n\n', 'normal'), (' error ', 'error'), (' ', 'normal'), ('cursor |', 'cursor'), ('\n ', 'normal'), ('shell', 'console'), (' ', 'normal'), ('stdout', 'stdout'), (' ', 'normal'), ('stderr', 'stderr'), ('\n', 'normal'))
  146.         for txTa in textAndTags:
  147.             text.insert(END, txTa[0], txTa[1])
  148.         
  149.         for element in self.themeElements.keys():
  150.             text.tag_bind(self.themeElements[element][0], '<ButtonPress-1>', (lambda event, elem = element: event.widget.winfo_toplevel().highlightTarget.set(elem)))
  151.         
  152.         text.config(state = DISABLED)
  153.         self.frameColourSet = Frame(frameCustom, relief = SOLID, borderwidth = 1)
  154.         frameFgBg = Frame(frameCustom)
  155.         labelCustomTitle = Label(frameCustom, text = 'Set Custom Highlighting')
  156.         buttonSetColour = Button(self.frameColourSet, text = 'Choose Colour for :', command = self.GetColour, highlightthickness = 0)
  157.         self.optMenuHighlightTarget = DynOptionMenu(self.frameColourSet, self.highlightTarget, None, highlightthickness = 0)
  158.         self.radioFg = Radiobutton(frameFgBg, variable = self.fgHilite, value = 1, text = 'Foreground', command = self.SetColourSampleBinding)
  159.         self.radioBg = Radiobutton(frameFgBg, variable = self.fgHilite, value = 0, text = 'Background', command = self.SetColourSampleBinding)
  160.         self.fgHilite.set(1)
  161.         buttonSaveCustomTheme = Button(frameCustom, text = 'Save as New Custom Theme', command = self.SaveAsNewTheme)
  162.         labelThemeTitle = Label(frameTheme, text = 'Select a Highlighting Theme')
  163.         labelTypeTitle = Label(frameTheme, text = 'Select : ')
  164.         self.radioThemeBuiltin = Radiobutton(frameTheme, variable = self.themeIsBuiltin, value = 1, command = self.SetThemeType, text = 'a Built-in Theme')
  165.         self.radioThemeCustom = Radiobutton(frameTheme, variable = self.themeIsBuiltin, value = 0, command = self.SetThemeType, text = 'a Custom Theme')
  166.         self.optMenuThemeBuiltin = DynOptionMenu(frameTheme, self.builtinTheme, None, command = None)
  167.         self.optMenuThemeCustom = DynOptionMenu(frameTheme, self.customTheme, None, command = None)
  168.         self.buttonDeleteCustomTheme = Button(frameTheme, text = 'Delete Custom Theme', command = self.DeleteCustomTheme)
  169.         frameCustom.pack(side = LEFT, padx = 5, pady = 10, expand = TRUE, fill = BOTH)
  170.         frameTheme.pack(side = LEFT, padx = 5, pady = 10, fill = Y)
  171.         labelCustomTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  172.         self.frameColourSet.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = X)
  173.         frameFgBg.pack(side = TOP, padx = 5, pady = 0)
  174.         self.textHighlightSample.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  175.         buttonSetColour.pack(side = TOP, expand = TRUE, fill = X, padx = 8, pady = 4)
  176.         self.optMenuHighlightTarget.pack(side = TOP, expand = TRUE, fill = X, padx = 8, pady = 3)
  177.         self.radioFg.pack(side = LEFT, anchor = E)
  178.         self.radioBg.pack(side = RIGHT, anchor = W)
  179.         buttonSaveCustomTheme.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  180.         labelThemeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  181.         labelTypeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  182.         self.radioThemeBuiltin.pack(side = TOP, anchor = W, padx = 5)
  183.         self.radioThemeCustom.pack(side = TOP, anchor = W, padx = 5, pady = 2)
  184.         self.optMenuThemeBuiltin.pack(side = TOP, fill = X, padx = 5, pady = 5)
  185.         self.optMenuThemeCustom.pack(side = TOP, fill = X, anchor = W, padx = 5, pady = 5)
  186.         self.buttonDeleteCustomTheme.pack(side = TOP, fill = X, padx = 5, pady = 5)
  187.         return frame
  188.  
  189.     
  190.     def CreatePageKeys(self):
  191.         self.bindingTarget = StringVar(self)
  192.         self.builtinKeys = StringVar(self)
  193.         self.customKeys = StringVar(self)
  194.         self.keysAreBuiltin = BooleanVar(self)
  195.         self.keyBinding = StringVar(self)
  196.         frame = self.tabPages.pages['Keys']['page']
  197.         frameCustom = Frame(frame, borderwidth = 2, relief = GROOVE)
  198.         frameKeySets = Frame(frame, borderwidth = 2, relief = GROOVE)
  199.         frameTarget = Frame(frameCustom)
  200.         labelCustomTitle = Label(frameCustom, text = 'Set Custom Key Bindings')
  201.         labelTargetTitle = Label(frameTarget, text = 'Action - Key(s)')
  202.         scrollTargetY = Scrollbar(frameTarget)
  203.         scrollTargetX = Scrollbar(frameTarget, orient = HORIZONTAL)
  204.         self.listBindings = Listbox(frameTarget, takefocus = FALSE, exportselection = FALSE)
  205.         self.listBindings.bind('<ButtonRelease-1>', self.KeyBindingSelected)
  206.         scrollTargetY.config(command = self.listBindings.yview)
  207.         scrollTargetX.config(command = self.listBindings.xview)
  208.         self.listBindings.config(yscrollcommand = scrollTargetY.set)
  209.         self.listBindings.config(xscrollcommand = scrollTargetX.set)
  210.         self.buttonNewKeys = Button(frameCustom, text = 'Get New Keys for Selection', command = self.GetNewKeys, state = DISABLED)
  211.         buttonSaveCustomKeys = Button(frameCustom, text = 'Save as New Custom Key Set', command = self.SaveAsNewKeySet)
  212.         labelKeysTitle = Label(frameKeySets, text = 'Select a Key Set')
  213.         labelTypeTitle = Label(frameKeySets, text = 'Select : ')
  214.         self.radioKeysBuiltin = Radiobutton(frameKeySets, variable = self.keysAreBuiltin, value = 1, command = self.SetKeysType, text = 'a Built-in Key Set')
  215.         self.radioKeysCustom = Radiobutton(frameKeySets, variable = self.keysAreBuiltin, value = 0, command = self.SetKeysType, text = 'a Custom Key Set')
  216.         self.optMenuKeysBuiltin = DynOptionMenu(frameKeySets, self.builtinKeys, None, command = None)
  217.         self.optMenuKeysCustom = DynOptionMenu(frameKeySets, self.customKeys, None, command = None)
  218.         self.buttonDeleteCustomKeys = Button(frameKeySets, text = 'Delete Custom Key Set', command = self.DeleteCustomKeys)
  219.         frameCustom.pack(side = LEFT, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  220.         frameKeySets.pack(side = LEFT, padx = 5, pady = 5, fill = Y)
  221.         labelCustomTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  222.         buttonSaveCustomKeys.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  223.         self.buttonNewKeys.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  224.         frameTarget.pack(side = LEFT, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  225.         frameTarget.columnconfigure(0, weight = 1)
  226.         frameTarget.rowconfigure(1, weight = 1)
  227.         labelTargetTitle.grid(row = 0, column = 0, columnspan = 2, sticky = W)
  228.         self.listBindings.grid(row = 1, column = 0, sticky = NSEW)
  229.         scrollTargetY.grid(row = 1, column = 1, sticky = NS)
  230.         scrollTargetX.grid(row = 2, column = 0, sticky = EW)
  231.         labelKeysTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  232.         labelTypeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  233.         self.radioKeysBuiltin.pack(side = TOP, anchor = W, padx = 5)
  234.         self.radioKeysCustom.pack(side = TOP, anchor = W, padx = 5, pady = 2)
  235.         self.optMenuKeysBuiltin.pack(side = TOP, fill = X, padx = 5, pady = 5)
  236.         self.optMenuKeysCustom.pack(side = TOP, fill = X, anchor = W, padx = 5, pady = 5)
  237.         self.buttonDeleteCustomKeys.pack(side = TOP, fill = X, padx = 5, pady = 5)
  238.         return frame
  239.  
  240.     
  241.     def CreatePageGeneral(self):
  242.         self.winWidth = StringVar(self)
  243.         self.winHeight = StringVar(self)
  244.         self.paraWidth = StringVar(self)
  245.         self.startupEdit = IntVar(self)
  246.         self.autoSave = IntVar(self)
  247.         self.encoding = StringVar(self)
  248.         self.userHelpBrowser = BooleanVar(self)
  249.         self.helpBrowser = StringVar(self)
  250.         frame = self.tabPages.pages['General']['page']
  251.         frameRun = Frame(frame, borderwidth = 2, relief = GROOVE)
  252.         frameSave = Frame(frame, borderwidth = 2, relief = GROOVE)
  253.         frameWinSize = Frame(frame, borderwidth = 2, relief = GROOVE)
  254.         frameParaSize = Frame(frame, borderwidth = 2, relief = GROOVE)
  255.         frameEncoding = Frame(frame, borderwidth = 2, relief = GROOVE)
  256.         frameHelp = Frame(frame, borderwidth = 2, relief = GROOVE)
  257.         labelRunTitle = Label(frameRun, text = 'Startup Preferences')
  258.         labelRunChoiceTitle = Label(frameRun, text = 'At Startup')
  259.         radioStartupEdit = Radiobutton(frameRun, variable = self.startupEdit, value = 1, command = self.SetKeysType, text = 'Open Edit Window')
  260.         radioStartupShell = Radiobutton(frameRun, variable = self.startupEdit, value = 0, command = self.SetKeysType, text = 'Open Shell Window')
  261.         labelSaveTitle = Label(frameSave, text = 'Autosave Preference')
  262.         labelRunSaveTitle = Label(frameSave, text = 'At Start of Run (F5)  ')
  263.         radioSaveAsk = Radiobutton(frameSave, variable = self.autoSave, value = 0, command = self.SetKeysType, text = 'Prompt to Save')
  264.         radioSaveAuto = Radiobutton(frameSave, variable = self.autoSave, value = 1, command = self.SetKeysType, text = 'No Prompt')
  265.         labelWinSizeTitle = Label(frameWinSize, text = 'Initial Window Size' + '  (in characters)')
  266.         labelWinWidthTitle = Label(frameWinSize, text = 'Width')
  267.         entryWinWidth = Entry(frameWinSize, textvariable = self.winWidth, width = 3)
  268.         labelWinHeightTitle = Label(frameWinSize, text = 'Height')
  269.         entryWinHeight = Entry(frameWinSize, textvariable = self.winHeight, width = 3)
  270.         labelParaWidthTitle = Label(frameParaSize, text = 'Paragraph reformat' + ' width (in characters)')
  271.         entryParaWidth = Entry(frameParaSize, textvariable = self.paraWidth, width = 3)
  272.         labelEncodingTitle = Label(frameEncoding, text = 'Default Source Encoding')
  273.         radioEncLocale = Radiobutton(frameEncoding, variable = self.encoding, value = 'locale', text = 'Locale-defined')
  274.         radioEncUTF8 = Radiobutton(frameEncoding, variable = self.encoding, value = 'utf-8', text = 'UTF-8')
  275.         radioEncNone = Radiobutton(frameEncoding, variable = self.encoding, value = 'none', text = 'None')
  276.         frameHelpList = Frame(frameHelp)
  277.         frameHelpListButtons = Frame(frameHelpList)
  278.         labelHelpListTitle = Label(frameHelpList, text = 'Additional Help Sources:')
  279.         scrollHelpList = Scrollbar(frameHelpList)
  280.         self.listHelp = Listbox(frameHelpList, height = 5, takefocus = FALSE, exportselection = FALSE)
  281.         scrollHelpList.config(command = self.listHelp.yview)
  282.         self.listHelp.config(yscrollcommand = scrollHelpList.set)
  283.         self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected)
  284.         self.buttonHelpListEdit = Button(frameHelpListButtons, text = 'Edit', state = DISABLED, width = 8, command = self.HelpListItemEdit)
  285.         self.buttonHelpListAdd = Button(frameHelpListButtons, text = 'Add', width = 8, command = self.HelpListItemAdd)
  286.         self.buttonHelpListRemove = Button(frameHelpListButtons, text = 'Remove', state = DISABLED, width = 8, command = self.HelpListItemRemove)
  287.         frameRun.pack(side = TOP, padx = 5, pady = 5, fill = X)
  288.         frameSave.pack(side = TOP, padx = 5, pady = 5, fill = X)
  289.         frameWinSize.pack(side = TOP, padx = 5, pady = 5, fill = X)
  290.         frameParaSize.pack(side = TOP, padx = 5, pady = 5, fill = X)
  291.         frameEncoding.pack(side = TOP, padx = 5, pady = 5, fill = X)
  292.         frameHelp.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  293.         labelRunTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  294.         labelRunChoiceTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  295.         radioStartupShell.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  296.         radioStartupEdit.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  297.         labelSaveTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  298.         labelRunSaveTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  299.         radioSaveAuto.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  300.         radioSaveAsk.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  301.         labelWinSizeTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  302.         entryWinHeight.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  303.         labelWinHeightTitle.pack(side = RIGHT, anchor = E, pady = 5)
  304.         entryWinWidth.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  305.         labelWinWidthTitle.pack(side = RIGHT, anchor = E, pady = 5)
  306.         labelParaWidthTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  307.         entryParaWidth.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  308.         labelEncodingTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  309.         radioEncNone.pack(side = RIGHT, anchor = E, pady = 5)
  310.         radioEncUTF8.pack(side = RIGHT, anchor = E, pady = 5)
  311.         radioEncLocale.pack(side = RIGHT, anchor = E, pady = 5)
  312.         frameHelpListButtons.pack(side = RIGHT, padx = 5, pady = 5, fill = Y)
  313.         frameHelpList.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  314.         labelHelpListTitle.pack(side = TOP, anchor = W)
  315.         scrollHelpList.pack(side = RIGHT, anchor = W, fill = Y)
  316.         self.listHelp.pack(side = LEFT, anchor = E, expand = TRUE, fill = BOTH)
  317.         self.buttonHelpListEdit.pack(side = TOP, anchor = W, pady = 5)
  318.         self.buttonHelpListAdd.pack(side = TOP, anchor = W)
  319.         self.buttonHelpListRemove.pack(side = TOP, anchor = W, pady = 5)
  320.         return frame
  321.  
  322.     
  323.     def AttachVarCallbacks(self):
  324.         self.fontSize.trace_variable('w', self.VarChanged_fontSize)
  325.         self.fontName.trace_variable('w', self.VarChanged_fontName)
  326.         self.fontBold.trace_variable('w', self.VarChanged_fontBold)
  327.         self.spaceNum.trace_variable('w', self.VarChanged_spaceNum)
  328.         self.colour.trace_variable('w', self.VarChanged_colour)
  329.         self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme)
  330.         self.customTheme.trace_variable('w', self.VarChanged_customTheme)
  331.         self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin)
  332.         self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget)
  333.         self.keyBinding.trace_variable('w', self.VarChanged_keyBinding)
  334.         self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys)
  335.         self.customKeys.trace_variable('w', self.VarChanged_customKeys)
  336.         self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin)
  337.         self.winWidth.trace_variable('w', self.VarChanged_winWidth)
  338.         self.winHeight.trace_variable('w', self.VarChanged_winHeight)
  339.         self.paraWidth.trace_variable('w', self.VarChanged_paraWidth)
  340.         self.startupEdit.trace_variable('w', self.VarChanged_startupEdit)
  341.         self.autoSave.trace_variable('w', self.VarChanged_autoSave)
  342.         self.encoding.trace_variable('w', self.VarChanged_encoding)
  343.  
  344.     
  345.     def VarChanged_fontSize(self, *params):
  346.         value = self.fontSize.get()
  347.         self.AddChangedItem('main', 'EditorWindow', 'font-size', value)
  348.  
  349.     
  350.     def VarChanged_fontName(self, *params):
  351.         value = self.fontName.get()
  352.         self.AddChangedItem('main', 'EditorWindow', 'font', value)
  353.  
  354.     
  355.     def VarChanged_fontBold(self, *params):
  356.         value = self.fontBold.get()
  357.         self.AddChangedItem('main', 'EditorWindow', 'font-bold', value)
  358.  
  359.     
  360.     def VarChanged_spaceNum(self, *params):
  361.         value = self.spaceNum.get()
  362.         self.AddChangedItem('main', 'Indent', 'num-spaces', value)
  363.  
  364.     
  365.     def VarChanged_colour(self, *params):
  366.         self.OnNewColourSet()
  367.  
  368.     
  369.     def VarChanged_builtinTheme(self, *params):
  370.         value = self.builtinTheme.get()
  371.         self.AddChangedItem('main', 'Theme', 'name', value)
  372.         self.PaintThemeSample()
  373.  
  374.     
  375.     def VarChanged_customTheme(self, *params):
  376.         value = self.customTheme.get()
  377.         if value != '- no custom themes -':
  378.             self.AddChangedItem('main', 'Theme', 'name', value)
  379.             self.PaintThemeSample()
  380.         
  381.  
  382.     
  383.     def VarChanged_themeIsBuiltin(self, *params):
  384.         value = self.themeIsBuiltin.get()
  385.         self.AddChangedItem('main', 'Theme', 'default', value)
  386.         if value:
  387.             self.VarChanged_builtinTheme()
  388.         else:
  389.             self.VarChanged_customTheme()
  390.  
  391.     
  392.     def VarChanged_highlightTarget(self, *params):
  393.         self.SetHighlightTarget()
  394.  
  395.     
  396.     def VarChanged_keyBinding(self, *params):
  397.         value = self.keyBinding.get()
  398.         keySet = self.customKeys.get()
  399.         event = self.listBindings.get(ANCHOR).split()[0]
  400.         if idleConf.IsCoreBinding(event):
  401.             self.AddChangedItem('keys', keySet, event, value)
  402.         else:
  403.             extName = idleConf.GetExtnNameForEvent(event)
  404.             extKeybindSection = extName + '_cfgBindings'
  405.             self.AddChangedItem('extensions', extKeybindSection, event, value)
  406.  
  407.     
  408.     def VarChanged_builtinKeys(self, *params):
  409.         value = self.builtinKeys.get()
  410.         self.AddChangedItem('main', 'Keys', 'name', value)
  411.         self.LoadKeysList(value)
  412.  
  413.     
  414.     def VarChanged_customKeys(self, *params):
  415.         value = self.customKeys.get()
  416.         if value != '- no custom keys -':
  417.             self.AddChangedItem('main', 'Keys', 'name', value)
  418.             self.LoadKeysList(value)
  419.         
  420.  
  421.     
  422.     def VarChanged_keysAreBuiltin(self, *params):
  423.         value = self.keysAreBuiltin.get()
  424.         self.AddChangedItem('main', 'Keys', 'default', value)
  425.         if value:
  426.             self.VarChanged_builtinKeys()
  427.         else:
  428.             self.VarChanged_customKeys()
  429.  
  430.     
  431.     def VarChanged_winWidth(self, *params):
  432.         value = self.winWidth.get()
  433.         self.AddChangedItem('main', 'EditorWindow', 'width', value)
  434.  
  435.     
  436.     def VarChanged_winHeight(self, *params):
  437.         value = self.winHeight.get()
  438.         self.AddChangedItem('main', 'EditorWindow', 'height', value)
  439.  
  440.     
  441.     def VarChanged_paraWidth(self, *params):
  442.         value = self.paraWidth.get()
  443.         self.AddChangedItem('main', 'FormatParagraph', 'paragraph', value)
  444.  
  445.     
  446.     def VarChanged_startupEdit(self, *params):
  447.         value = self.startupEdit.get()
  448.         self.AddChangedItem('main', 'General', 'editor-on-startup', value)
  449.  
  450.     
  451.     def VarChanged_autoSave(self, *params):
  452.         value = self.autoSave.get()
  453.         self.AddChangedItem('main', 'General', 'autosave', value)
  454.  
  455.     
  456.     def VarChanged_encoding(self, *params):
  457.         value = self.encoding.get()
  458.         self.AddChangedItem('main', 'EditorWindow', 'encoding', value)
  459.  
  460.     
  461.     def ResetChangedItems(self):
  462.         self.changedItems = {
  463.             'main': { },
  464.             'highlight': { },
  465.             'keys': { },
  466.             'extensions': { } }
  467.  
  468.     
  469.     def AddChangedItem(self, type, section, item, value):
  470.         value = str(value)
  471.         if not self.changedItems[type].has_key(section):
  472.             self.changedItems[type][section] = { }
  473.         
  474.         self.changedItems[type][section][item] = value
  475.  
  476.     
  477.     def GetDefaultItems(self):
  478.         dItems = {
  479.             'main': { },
  480.             'highlight': { },
  481.             'keys': { },
  482.             'extensions': { } }
  483.         for configType in dItems.keys():
  484.             sections = idleConf.GetSectionList('default', configType)
  485.             for section in sections:
  486.                 dItems[configType][section] = { }
  487.                 options = idleConf.defaultCfg[configType].GetOptionList(section)
  488.                 for option in options:
  489.                     dItems[configType][section][option] = idleConf.defaultCfg[configType].Get(section, option)
  490.                 
  491.             
  492.         
  493.         return dItems
  494.  
  495.     
  496.     def SetThemeType(self):
  497.         if self.themeIsBuiltin.get():
  498.             self.optMenuThemeBuiltin.config(state = NORMAL)
  499.             self.optMenuThemeCustom.config(state = DISABLED)
  500.             self.buttonDeleteCustomTheme.config(state = DISABLED)
  501.         else:
  502.             self.optMenuThemeBuiltin.config(state = DISABLED)
  503.             self.radioThemeCustom.config(state = NORMAL)
  504.             self.optMenuThemeCustom.config(state = NORMAL)
  505.             self.buttonDeleteCustomTheme.config(state = NORMAL)
  506.  
  507.     
  508.     def SetKeysType(self):
  509.         if self.keysAreBuiltin.get():
  510.             self.optMenuKeysBuiltin.config(state = NORMAL)
  511.             self.optMenuKeysCustom.config(state = DISABLED)
  512.             self.buttonDeleteCustomKeys.config(state = DISABLED)
  513.         else:
  514.             self.optMenuKeysBuiltin.config(state = DISABLED)
  515.             self.radioKeysCustom.config(state = NORMAL)
  516.             self.optMenuKeysCustom.config(state = NORMAL)
  517.             self.buttonDeleteCustomKeys.config(state = NORMAL)
  518.  
  519.     
  520.     def GetNewKeys(self):
  521.         listIndex = self.listBindings.index(ANCHOR)
  522.         binding = self.listBindings.get(listIndex)
  523.         bindName = binding.split()[0]
  524.         if self.keysAreBuiltin.get():
  525.             currentKeySetName = self.builtinKeys.get()
  526.         else:
  527.             currentKeySetName = self.customKeys.get()
  528.         currentBindings = idleConf.GetCurrentKeySet()
  529.         if currentKeySetName in self.changedItems['keys'].keys():
  530.             keySetChanges = self.changedItems['keys'][currentKeySetName]
  531.             for event in keySetChanges.keys():
  532.                 currentBindings[event] = keySetChanges[event].split()
  533.             
  534.         
  535.         currentKeySequences = currentBindings.values()
  536.         newKeys = GetKeysDialog(self, 'Get New Keys', bindName, currentKeySequences).result
  537.         if newKeys:
  538.             if self.keysAreBuiltin.get():
  539.                 message = 'Your changes will be saved as a new Custom Key Set. ' + 'Enter a name for your new Custom Key Set below.'
  540.                 newKeySet = self.GetNewKeysName(message)
  541.                 if not newKeySet:
  542.                     self.listBindings.select_set(listIndex)
  543.                     self.listBindings.select_anchor(listIndex)
  544.                     return None
  545.                 else:
  546.                     self.CreateNewKeySet(newKeySet)
  547.             
  548.             self.listBindings.delete(listIndex)
  549.             self.listBindings.insert(listIndex, bindName + ' - ' + newKeys)
  550.             self.listBindings.select_set(listIndex)
  551.             self.listBindings.select_anchor(listIndex)
  552.             self.keyBinding.set(newKeys)
  553.         else:
  554.             self.listBindings.select_set(listIndex)
  555.             self.listBindings.select_anchor(listIndex)
  556.  
  557.     
  558.     def GetNewKeysName(self, message):
  559.         usedNames = idleConf.GetSectionList('user', 'keys') + idleConf.GetSectionList('default', 'keys')
  560.         newKeySet = GetCfgSectionNameDialog(self, 'New Custom Key Set', message, usedNames).result
  561.         return newKeySet
  562.  
  563.     
  564.     def SaveAsNewKeySet(self):
  565.         newKeysName = self.GetNewKeysName('New Key Set Name:')
  566.         if newKeysName:
  567.             self.CreateNewKeySet(newKeysName)
  568.         
  569.  
  570.     
  571.     def KeyBindingSelected(self, event):
  572.         self.buttonNewKeys.config(state = NORMAL)
  573.  
  574.     
  575.     def CreateNewKeySet(self, newKeySetName):
  576.         if self.keysAreBuiltin.get():
  577.             prevKeySetName = self.builtinKeys.get()
  578.         else:
  579.             prevKeySetName = self.customKeys.get()
  580.         prevKeys = idleConf.GetCoreKeys(prevKeySetName)
  581.         newKeys = { }
  582.         for event in prevKeys.keys():
  583.             eventName = event[2:-2]
  584.             binding = string.join(prevKeys[event])
  585.             newKeys[eventName] = binding
  586.         
  587.         if prevKeySetName in self.changedItems['keys'].keys():
  588.             keySetChanges = self.changedItems['keys'][prevKeySetName]
  589.             for event in keySetChanges.keys():
  590.                 newKeys[event] = keySetChanges[event]
  591.             
  592.         
  593.         self.SaveNewKeySet(newKeySetName, newKeys)
  594.         customKeyList = idleConf.GetSectionList('user', 'keys')
  595.         customKeyList.sort()
  596.         self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName)
  597.         self.keysAreBuiltin.set(0)
  598.         self.SetKeysType()
  599.  
  600.     
  601.     def LoadKeysList(self, keySetName):
  602.         reselect = 0
  603.         newKeySet = 0
  604.         if self.listBindings.curselection():
  605.             reselect = 1
  606.             listIndex = self.listBindings.index(ANCHOR)
  607.         
  608.         keySet = idleConf.GetKeySet(keySetName)
  609.         bindNames = keySet.keys()
  610.         bindNames.sort()
  611.         self.listBindings.delete(0, END)
  612.         for bindName in bindNames:
  613.             key = string.join(keySet[bindName])
  614.             bindName = bindName[2:-2]
  615.             if keySetName in self.changedItems['keys'].keys():
  616.                 if bindName in self.changedItems['keys'][keySetName].keys():
  617.                     key = self.changedItems['keys'][keySetName][bindName]
  618.                 
  619.             
  620.             self.listBindings.insert(END, bindName + ' - ' + key)
  621.         
  622.         if reselect:
  623.             self.listBindings.see(listIndex)
  624.             self.listBindings.select_set(listIndex)
  625.             self.listBindings.select_anchor(listIndex)
  626.         
  627.  
  628.     
  629.     def DeleteCustomKeys(self):
  630.         keySetName = self.customKeys.get()
  631.         if not tkMessageBox.askyesno('Delete Key Set', 'Are you sure you wish ' + 'to delete the key set %r ?' % keySetName, parent = self):
  632.             return None
  633.         
  634.         idleConf.userCfg['keys'].remove_section(keySetName)
  635.         if self.changedItems['keys'].has_key(keySetName):
  636.             del self.changedItems['keys'][keySetName]
  637.         
  638.         idleConf.userCfg['keys'].Save()
  639.         itemList = idleConf.GetSectionList('user', 'keys')
  640.         itemList.sort()
  641.         if not itemList:
  642.             self.radioKeysCustom.config(state = DISABLED)
  643.             self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -')
  644.         else:
  645.             self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
  646.         self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
  647.         self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
  648.         self.Apply()
  649.         self.SetKeysType()
  650.  
  651.     
  652.     def DeleteCustomTheme(self):
  653.         themeName = self.customTheme.get()
  654.         if not tkMessageBox.askyesno('Delete Theme', 'Are you sure you wish ' + 'to delete the theme %r ?' % (themeName,), parent = self):
  655.             return None
  656.         
  657.         idleConf.userCfg['highlight'].remove_section(themeName)
  658.         if self.changedItems['highlight'].has_key(themeName):
  659.             del self.changedItems['highlight'][themeName]
  660.         
  661.         idleConf.userCfg['highlight'].Save()
  662.         itemList = idleConf.GetSectionList('user', 'highlight')
  663.         itemList.sort()
  664.         if not itemList:
  665.             self.radioThemeCustom.config(state = DISABLED)
  666.             self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -')
  667.         else:
  668.             self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
  669.         self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
  670.         self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
  671.         self.Apply()
  672.         self.SetThemeType()
  673.  
  674.     
  675.     def GetColour(self):
  676.         target = self.highlightTarget.get()
  677.         prevColour = self.frameColourSet.cget('bg')
  678.         (rgbTuplet, colourString) = tkColorChooser.askcolor(parent = self, title = 'Pick new colour for : ' + target, initialcolor = prevColour)
  679.         if colourString and colourString != prevColour:
  680.             if self.themeIsBuiltin.get():
  681.                 message = 'Your changes will be saved as a new Custom Theme. ' + 'Enter a name for your new Custom Theme below.'
  682.                 newTheme = self.GetNewThemeName(message)
  683.                 if not newTheme:
  684.                     return None
  685.                 else:
  686.                     self.CreateNewTheme(newTheme)
  687.                     self.colour.set(colourString)
  688.             else:
  689.                 self.colour.set(colourString)
  690.         
  691.  
  692.     
  693.     def OnNewColourSet(self):
  694.         newColour = self.colour.get()
  695.         self.frameColourSet.config(bg = newColour)
  696.         if self.fgHilite.get():
  697.             plane = 'foreground'
  698.         else:
  699.             plane = 'background'
  700.         sampleElement = self.themeElements[self.highlightTarget.get()][0]
  701.         self.textHighlightSample.tag_config(sampleElement, **{
  702.             plane: newColour })
  703.         theme = self.customTheme.get()
  704.         themeElement = sampleElement + '-' + plane
  705.         self.AddChangedItem('highlight', theme, themeElement, newColour)
  706.  
  707.     
  708.     def GetNewThemeName(self, message):
  709.         usedNames = idleConf.GetSectionList('user', 'highlight') + idleConf.GetSectionList('default', 'highlight')
  710.         newTheme = GetCfgSectionNameDialog(self, 'New Custom Theme', message, usedNames).result
  711.         return newTheme
  712.  
  713.     
  714.     def SaveAsNewTheme(self):
  715.         newThemeName = self.GetNewThemeName('New Theme Name:')
  716.         if newThemeName:
  717.             self.CreateNewTheme(newThemeName)
  718.         
  719.  
  720.     
  721.     def CreateNewTheme(self, newThemeName):
  722.         if self.themeIsBuiltin.get():
  723.             themeType = 'default'
  724.             themeName = self.builtinTheme.get()
  725.         else:
  726.             themeType = 'user'
  727.             themeName = self.customTheme.get()
  728.         newTheme = idleConf.GetThemeDict(themeType, themeName)
  729.         if themeName in self.changedItems['highlight'].keys():
  730.             themeChanges = self.changedItems['highlight'][themeName]
  731.             for element in themeChanges.keys():
  732.                 newTheme[element] = themeChanges[element]
  733.             
  734.         
  735.         self.SaveNewTheme(newThemeName, newTheme)
  736.         customThemeList = idleConf.GetSectionList('user', 'highlight')
  737.         customThemeList.sort()
  738.         self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName)
  739.         self.themeIsBuiltin.set(0)
  740.         self.SetThemeType()
  741.  
  742.     
  743.     def OnListFontButtonRelease(self, event):
  744.         font = self.listFontName.get(ANCHOR)
  745.         self.fontName.set(font.lower())
  746.         self.SetFontSample()
  747.  
  748.     
  749.     def SetFontSample(self, event = None):
  750.         fontName = self.fontName.get()
  751.         if self.fontBold.get():
  752.             fontWeight = tkFont.BOLD
  753.         else:
  754.             fontWeight = tkFont.NORMAL
  755.         self.editFont.config(size = self.fontSize.get(), weight = fontWeight, family = fontName)
  756.  
  757.     
  758.     def SetHighlightTarget(self):
  759.         if self.highlightTarget.get() == 'Cursor':
  760.             self.radioFg.config(state = DISABLED)
  761.             self.radioBg.config(state = DISABLED)
  762.             self.fgHilite.set(1)
  763.         else:
  764.             self.radioFg.config(state = NORMAL)
  765.             self.radioBg.config(state = NORMAL)
  766.             self.fgHilite.set(1)
  767.         self.SetColourSample()
  768.  
  769.     
  770.     def SetColourSampleBinding(self, *args):
  771.         self.SetColourSample()
  772.  
  773.     
  774.     def SetColourSample(self):
  775.         tag = self.themeElements[self.highlightTarget.get()][0]
  776.         if self.fgHilite.get():
  777.             plane = 'foreground'
  778.         else:
  779.             plane = 'background'
  780.         colour = self.textHighlightSample.tag_cget(tag, plane)
  781.         self.frameColourSet.config(bg = colour)
  782.  
  783.     
  784.     def PaintThemeSample(self):
  785.         if self.themeIsBuiltin.get():
  786.             theme = self.builtinTheme.get()
  787.         else:
  788.             theme = self.customTheme.get()
  789.         for elementTitle in self.themeElements.keys():
  790.             element = self.themeElements[elementTitle][0]
  791.             colours = idleConf.GetHighlight(theme, element)
  792.             if element == 'cursor':
  793.                 colours['background'] = idleConf.GetHighlight(theme, 'normal', fgBg = 'bg')
  794.             
  795.             if theme in self.changedItems['highlight'].keys():
  796.                 themeDict = self.changedItems['highlight'][theme]
  797.                 if themeDict.has_key(element + '-foreground'):
  798.                     colours['foreground'] = themeDict[element + '-foreground']
  799.                 
  800.                 if themeDict.has_key(element + '-background'):
  801.                     colours['background'] = themeDict[element + '-background']
  802.                 
  803.             
  804.             self.textHighlightSample.tag_config(element, **colours)
  805.         
  806.         self.SetColourSample()
  807.  
  808.     
  809.     def HelpSourceSelected(self, event):
  810.         self.SetHelpListButtonStates()
  811.  
  812.     
  813.     def SetHelpListButtonStates(self):
  814.         if self.listHelp.size() < 1:
  815.             self.buttonHelpListEdit.config(state = DISABLED)
  816.             self.buttonHelpListRemove.config(state = DISABLED)
  817.         elif self.listHelp.curselection():
  818.             self.buttonHelpListEdit.config(state = NORMAL)
  819.             self.buttonHelpListRemove.config(state = NORMAL)
  820.         else:
  821.             self.buttonHelpListEdit.config(state = DISABLED)
  822.             self.buttonHelpListRemove.config(state = DISABLED)
  823.  
  824.     
  825.     def HelpListItemAdd(self):
  826.         helpSource = GetHelpSourceDialog(self, 'New Help Source').result
  827.         if helpSource:
  828.             self.userHelpList.append((helpSource[0], helpSource[1]))
  829.             self.listHelp.insert(END, helpSource[0])
  830.             self.UpdateUserHelpChangedItems()
  831.         
  832.         self.SetHelpListButtonStates()
  833.  
  834.     
  835.     def HelpListItemEdit(self):
  836.         itemIndex = self.listHelp.index(ANCHOR)
  837.         helpSource = self.userHelpList[itemIndex]
  838.         newHelpSource = GetHelpSourceDialog(self, 'Edit Help Source', menuItem = helpSource[0], filePath = helpSource[1]).result
  839.         if not newHelpSource or newHelpSource == helpSource:
  840.             return None
  841.         
  842.         self.userHelpList[itemIndex] = newHelpSource
  843.         self.listHelp.delete(itemIndex)
  844.         self.listHelp.insert(itemIndex, newHelpSource[0])
  845.         self.UpdateUserHelpChangedItems()
  846.         self.SetHelpListButtonStates()
  847.  
  848.     
  849.     def HelpListItemRemove(self):
  850.         itemIndex = self.listHelp.index(ANCHOR)
  851.         del self.userHelpList[itemIndex]
  852.         self.listHelp.delete(itemIndex)
  853.         self.UpdateUserHelpChangedItems()
  854.         self.SetHelpListButtonStates()
  855.  
  856.     
  857.     def UpdateUserHelpChangedItems(self):
  858.         '''Clear and rebuild the HelpFiles section in self.changedItems'''
  859.         self.changedItems['main']['HelpFiles'] = { }
  860.         for num in range(1, len(self.userHelpList) + 1):
  861.             self.AddChangedItem('main', 'HelpFiles', str(num), string.join(self.userHelpList[num - 1][:2], ';'))
  862.         
  863.  
  864.     
  865.     def LoadFontCfg(self):
  866.         fonts = list(tkFont.families(self))
  867.         fonts.sort()
  868.         for font in fonts:
  869.             self.listFontName.insert(END, font)
  870.         
  871.         configuredFont = idleConf.GetOption('main', 'EditorWindow', 'font', default = 'courier')
  872.         lc_configuredFont = configuredFont.lower()
  873.         self.fontName.set(lc_configuredFont)
  874.         lc_fonts = [ s.lower() for s in fonts ]
  875.         fontSize = idleConf.GetOption('main', 'EditorWindow', 'font-size', default = '10')
  876.         self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', '16', '18', '20', '22'), fontSize)
  877.         self.fontBold.set(idleConf.GetOption('main', 'EditorWindow', 'font-bold', default = 0, type = 'bool'))
  878.         self.SetFontSample()
  879.  
  880.     
  881.     def LoadTabCfg(self):
  882.         spaceNum = idleConf.GetOption('main', 'Indent', 'num-spaces', default = 4, type = 'int')
  883.         self.spaceNum.set(spaceNum)
  884.  
  885.     
  886.     def LoadThemeCfg(self):
  887.         self.themeIsBuiltin.set(idleConf.GetOption('main', 'Theme', 'default', type = 'bool', default = 1))
  888.         currentOption = idleConf.CurrentTheme()
  889.         if self.themeIsBuiltin.get():
  890.             itemList = idleConf.GetSectionList('default', 'highlight')
  891.             itemList.sort()
  892.             self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
  893.             itemList = idleConf.GetSectionList('user', 'highlight')
  894.             itemList.sort()
  895.             if not itemList:
  896.                 self.radioThemeCustom.config(state = DISABLED)
  897.                 self.customTheme.set('- no custom themes -')
  898.             else:
  899.                 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
  900.         else:
  901.             itemList = idleConf.GetSectionList('user', 'highlight')
  902.             itemList.sort()
  903.             self.optMenuThemeCustom.SetMenu(itemList, currentOption)
  904.             itemList = idleConf.GetSectionList('default', 'highlight')
  905.             itemList.sort()
  906.             self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
  907.         self.SetThemeType()
  908.         themeNames = self.themeElements.keys()
  909.         themeNames.sort(self._ConfigDialog__ThemeNameIndexCompare)
  910.         self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
  911.         self.PaintThemeSample()
  912.         self.SetHighlightTarget()
  913.  
  914.     
  915.     def __ThemeNameIndexCompare(self, a, b):
  916.         if self.themeElements[a][1] < self.themeElements[b][1]:
  917.             return -1
  918.         elif self.themeElements[a][1] == self.themeElements[b][1]:
  919.             return 0
  920.         else:
  921.             return 1
  922.  
  923.     
  924.     def LoadKeyCfg(self):
  925.         self.keysAreBuiltin.set(idleConf.GetOption('main', 'Keys', 'default', type = 'bool', default = 1))
  926.         currentOption = idleConf.CurrentKeys()
  927.         if self.keysAreBuiltin.get():
  928.             itemList = idleConf.GetSectionList('default', 'keys')
  929.             itemList.sort()
  930.             self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
  931.             itemList = idleConf.GetSectionList('user', 'keys')
  932.             itemList.sort()
  933.             if not itemList:
  934.                 self.radioKeysCustom.config(state = DISABLED)
  935.                 self.customKeys.set('- no custom keys -')
  936.             else:
  937.                 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
  938.         else:
  939.             itemList = idleConf.GetSectionList('user', 'keys')
  940.             itemList.sort()
  941.             self.optMenuKeysCustom.SetMenu(itemList, currentOption)
  942.             itemList = idleConf.GetSectionList('default', 'keys')
  943.             itemList.sort()
  944.             self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
  945.         self.SetKeysType()
  946.         keySetName = idleConf.CurrentKeys()
  947.         self.LoadKeysList(keySetName)
  948.  
  949.     
  950.     def LoadGeneralCfg(self):
  951.         self.startupEdit.set(idleConf.GetOption('main', 'General', 'editor-on-startup', default = 1, type = 'bool'))
  952.         self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', default = 0, type = 'bool'))
  953.         self.winWidth.set(idleConf.GetOption('main', 'EditorWindow', 'width'))
  954.         self.winHeight.set(idleConf.GetOption('main', 'EditorWindow', 'height'))
  955.         self.paraWidth.set(idleConf.GetOption('main', 'FormatParagraph', 'paragraph'))
  956.         self.encoding.set(idleConf.GetOption('main', 'EditorWindow', 'encoding', default = 'none'))
  957.         self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
  958.         for helpItem in self.userHelpList:
  959.             self.listHelp.insert(END, helpItem[0])
  960.         
  961.         self.SetHelpListButtonStates()
  962.  
  963.     
  964.     def LoadConfigs(self):
  965.         '''
  966.         load configuration from default and user config files and populate
  967.         the widgets on the config dialog pages.
  968.         '''
  969.         self.LoadFontCfg()
  970.         self.LoadTabCfg()
  971.         self.LoadThemeCfg()
  972.         self.LoadKeyCfg()
  973.         self.LoadGeneralCfg()
  974.  
  975.     
  976.     def SaveNewKeySet(self, keySetName, keySet):
  977.         '''
  978.         save a newly created core key set.
  979.         keySetName - string, the name of the new key set
  980.         keySet - dictionary containing the new key set
  981.         '''
  982.         if not idleConf.userCfg['keys'].has_section(keySetName):
  983.             idleConf.userCfg['keys'].add_section(keySetName)
  984.         
  985.         for event in keySet.keys():
  986.             value = keySet[event]
  987.             idleConf.userCfg['keys'].SetOption(keySetName, event, value)
  988.         
  989.  
  990.     
  991.     def SaveNewTheme(self, themeName, theme):
  992.         '''
  993.         save a newly created theme.
  994.         themeName - string, the name of the new theme
  995.         theme - dictionary containing the new theme
  996.         '''
  997.         if not idleConf.userCfg['highlight'].has_section(themeName):
  998.             idleConf.userCfg['highlight'].add_section(themeName)
  999.         
  1000.         for element in theme.keys():
  1001.             value = theme[element]
  1002.             idleConf.userCfg['highlight'].SetOption(themeName, element, value)
  1003.         
  1004.  
  1005.     
  1006.     def SetUserValue(self, configType, section, item, value):
  1007.         if idleConf.defaultCfg[configType].has_option(section, item):
  1008.             if idleConf.defaultCfg[configType].Get(section, item) == value:
  1009.                 return idleConf.userCfg[configType].RemoveOption(section, item)
  1010.             
  1011.         
  1012.         return idleConf.userCfg[configType].SetOption(section, item, value)
  1013.  
  1014.     
  1015.     def SaveAllChangedConfigs(self):
  1016.         '''Save configuration changes to the user config file.'''
  1017.         idleConf.userCfg['main'].Save()
  1018.         for configType in self.changedItems.keys():
  1019.             cfgTypeHasChanges = False
  1020.             for section in self.changedItems[configType].keys():
  1021.                 if section == 'HelpFiles':
  1022.                     idleConf.userCfg['main'].remove_section('HelpFiles')
  1023.                     cfgTypeHasChanges = True
  1024.                 
  1025.                 for item in self.changedItems[configType][section].keys():
  1026.                     value = self.changedItems[configType][section][item]
  1027.                     if self.SetUserValue(configType, section, item, value):
  1028.                         cfgTypeHasChanges = True
  1029.                         continue
  1030.                 
  1031.             
  1032.             if cfgTypeHasChanges:
  1033.                 idleConf.userCfg[configType].Save()
  1034.                 continue
  1035.         
  1036.         for configType in [
  1037.             'keys',
  1038.             'highlight']:
  1039.             idleConf.userCfg[configType].Save()
  1040.         
  1041.         self.ResetChangedItems()
  1042.  
  1043.     
  1044.     def DeactivateCurrentConfig(self):
  1045.         winInstances = self.parent.instance_dict.keys()
  1046.         for instance in winInstances:
  1047.             instance.RemoveKeybindings()
  1048.         
  1049.  
  1050.     
  1051.     def ActivateConfigChanges(self):
  1052.         '''Dynamically apply configuration changes'''
  1053.         winInstances = self.parent.instance_dict.keys()
  1054.         for instance in winInstances:
  1055.             instance.ResetColorizer()
  1056.             instance.ResetFont()
  1057.             instance.set_notabs_indentwidth()
  1058.             instance.ApplyKeybindings()
  1059.             instance.reset_help_menu_entries()
  1060.         
  1061.  
  1062.     
  1063.     def Cancel(self):
  1064.         self.destroy()
  1065.  
  1066.     
  1067.     def Ok(self):
  1068.         self.Apply()
  1069.         self.destroy()
  1070.  
  1071.     
  1072.     def Apply(self):
  1073.         self.DeactivateCurrentConfig()
  1074.         self.SaveAllChangedConfigs()
  1075.         self.ActivateConfigChanges()
  1076.  
  1077.     
  1078.     def Help(self):
  1079.         pass
  1080.  
  1081.  
  1082. if __name__ == '__main__':
  1083.     root = Tk()
  1084.     Button(root, text = 'Dialog', command = (lambda : ConfigDialog(root, 'Settings'))).pack()
  1085.     root.instance_dict = { }
  1086.     root.mainloop()
  1087.  
  1088.